package com.peteralbus.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * The type Earthquake info.
 *
 * @author PeterAlbus
 */
@Slf4j
@ToString //注解的本质为了简化代码
@Data  //注在类上，提供类的get、set、equals、hashCode、canEqual、toString方法
@AllArgsConstructor //全参构造
@NoArgsConstructor  //无参构造
public class EarthquakeInfo implements Serializable//需要把对象的状态信息通过网络进行传输，
                   // 或者需要将对象的状态信息持久化，以便将来使用时都需要把对象进行序列化
{
    //@TableId注解是专门用在主键上的注解，如果数据库中的主键字段名和实体中的属性名，
    // 不一样且不是驼峰之类的对应关系，可以在实体中表示主键的属性上加@Tableid注解，并指定@Tableid注解的value属性值为表中主键的字段名既可以对应上。
    @TableId(type= IdType.AUTO) //比如数据中的表中的字段是vote_id，但是实体类是voteId。那么就需要在voteId上打上这个注解
    @JsonFormat(shape = JsonFormat.Shape.STRING)//@JsonFormat注解是一个时间格式化注解，比如我们存储在mysql中的数据是date类型的，
    // 当我们读取出来封装在实体类中的时候，就会变成英文时间格式，而不是yyyy-MM-dd HH:mm:ss这样的中文时间
    //要注意的是，它只会在声明返回类型为json时，比如使用@ResponseBody返回json数据的时候，才会返回格式化的yyyy-MM-dd HH:mm:ss时间，
    // 如果直接使用System.out.println()输出的话，仍然是类似“Fri Dec 01 21:05:20 CST 2017”这样的时间样式。
    //@JsonFormat 用来表示json序列化的一种格式或者类型，shap表示序列化后的一种类型
    private Long earthquakeId;
    private String earthquakeName;
    private Double magnitude;
    private Double highIntensity;
    private Double longitude;
    private Double latitude;
    private Double depth;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")// @DateTimeFormat 注解的 pattern
    // 属性值指定的日期时间格式并不是将要转换成的日期格式，这个指定的格式是和传入的参数对应的，
    // 指定传参的形式为2018-08-02 22:05:55 //入参格式化
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    // 出参格式化调用接口的返回结果为："date": "2018-08-01T14:25:31.296+0000"
    //这个格式并不是我们想要的,ackson在序列化时间时是按照国际标准时间GMT进行格式化的，而在国内默认时区使用的是CST时区，两者相差8小时
    private LocalDateTime earthquakeTime;
    @TableField(exist = false)
    //比如在实体类中有一个属性为remark，但是在数据库中没有这个字段，
    // 但是在执行插入操作时给实体类的remark属性赋值了，那么可以通过在实体类的remark属性上添加
    private List<IntensityLine> intensityLineList=new ArrayList<>();

    /**
     * Gets intensity.
     *
     * @param x1 The first regression constant of the regression equation(for long radius)
     * @param y1 the second regression constant of the regression equation(for long radius)
     * @param z1 the third regression constant of the regression equation(for long radius)
     * @param b1 the fourth regression constant of the regression equation(for long radius)
     * @param e1 the fifth regression constant of the regression equation(for long radius)
     * @param x2 The first regression constant of the regression equation(for short radius)
     * @param y2 the second regression constant of the regression equation(for short radius)
     * @param z2 the third regression constant of the regression equation(for short radius)
     * @param b2 the fourth regression constant of the regression equation(for short radius)
     * @param e2 the fifth regression constant of the regression equation(for short radius)
     */
    public void getIntensity(double x1,double y1,double z1,double b1,double e1,double x2,double y2,double z2,double b2,double e2)
    {
        double longRadius =0,shortRadius = 0;
        double ia=x1+y1*magnitude-z1*Math.log10(longRadius+b1)+e1;
        double ib=x2+y2*magnitude-z2*Math.log10(shortRadius+b2)+e2;
        log.info("震中烈度:"+ia+"/"+ib);
        setHighIntensity(ia);
        int intensity=(int)ia;
        intensityLineList.clear();
        int count=0;
        while (intensity>3)
        {
            longRadius=Math.pow(10,-(intensity-x1-e1-y1*magnitude)/z1)-b1;
            shortRadius=Math.pow(10,-(intensity-x2-e2-y2*magnitude)/z2)-b2;
            IntensityLine intensityLine=new IntensityLine(longRadius,shortRadius,-20.0,intensity,earthquakeId);
            intensityLineList.add(intensityLine);
            intensity--;
            count++;
        }
    }

    /**
     * Gets intensity by distance.
     *
     * @param x1    the x 1
     * @param y1    the y 1
     * @param z1    the z 1
     * @param b1    the b 1
     * @param e1    the e 1
     * @param x2    the x 2
     * @param y2    the y 2
     * @param z2    the z 2
     * @param b2    the b 2
     * @param e2    the e 2
     * @param meter the meter
     * @return the intensity by distance
     */
    public Double getIntensityByDistance(double x1,double y1,double z1,double b1,double e1,double x2,double y2,double z2,double b2,double e2,Double meter)
    {
        double kilometer=meter/1000;
        return x1+y1*magnitude-z1*Math.log10(kilometer+b1)+e1;
    }

    /**
     * Gets intensity , use ln.
     *
     * @param x1 The first regression constant of the regression equation(for long radius)
     * @param y1 the second regression constant of the regression equation(for long radius)
     * @param z1 the third regression constant of the regression equation(for long radius)
     * @param b1 the fourth regression constant of the regression equation(for long radius)
     * @param x2 The first regression constant of the regression equation(for short radius)
     * @param y2 the second regression constant of the regression equation(for short radius)
     * @param z2 the third regression constant of the regression equation(for short radius)
     * @param b2 the fourth regression constant of the regression equation(for short radius)
     */
    public void getIntensityLn(double x1,double y1,double z1,double b1,double x2,double y2,double z2,double b2)
    {
        double longRadius =0,shortRadius = 0;
        double ia=x1+y1*magnitude-z1*Math.log10(longRadius+b1);
        double ib=x2+y2*magnitude-z2*Math.log10(shortRadius+b2);
        System.out.println("震中烈度:"+ia+"/"+ib);
        setHighIntensity(ia);
        int intensity=(int)ia;
        intensityLineList.clear();
        while (intensity>1)
        {
            longRadius=Math.exp(-(intensity-x1-y1*magnitude)/z1)-b1;
            shortRadius=Math.exp(-(intensity-x2-y2*magnitude)/z2)-b2;
            IntensityLine intensityLine=new IntensityLine(longRadius,shortRadius,-20.0,intensity,earthquakeId);
            intensityLineList.add(intensityLine);
            intensity--;
        }
    }

    /**
     * Gets formatted time.
     *
     * @return the formatted time
     */
    public String getFormattedTime()
    {
        //将earthquakeTime转化为"yyyy-MM-dd HH:mm:ss"格式
        DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTimeFormatter.format(earthquakeTime);
    }
}
